Treat empty cache objects as misses to prevent poisoning#467
Treat empty cache objects as misses to prevent poisoning#467jeremy wants to merge 1 commit intowillnorris:mainfrom
Conversation
When S3/GCS lifecycle rules delete cached objects, the cache might return empty data instead of indicating a cache miss. This causes httpcache to serve blank responses with "unknown format" errors. This change treats zero-length objects as cache misses, ensuring imageproxy fetches fresh copies from the origin when cached objects are deleted by lifecycle rules, and refactors S3 and GCS caches to use interfaces so this behavior can be tested. Fixes willnorris#248
|
Is this unique to s3 and gcs, or is this a layer that should sit in front of whatever caching backend is in use? |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #467 +/- ##
===========================================
- Coverage 85.21% 67.43% -17.79%
===========================================
Files 6 12 +6
Lines 717 1213 +496
===========================================
+ Hits 611 818 +207
- Misses 76 357 +281
- Partials 30 38 +8 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Indeed, this is an odd band-aid over some underlying issue and it doesn't apply to just S3/GCS. Turns out @flavorjones fixed the root cause in an internal patch that fixed a weird segfault: After his patch, empty bodies stopped showing up in the cache. These weren't due to lifecycle rules at all—they were from imageproxy caching malformed 304s. @flavorjones could you open a PR with your fix? |
oh, fascinating. Yeah, I'd love to hear more about that issue and see the patch. |
Sure, will do. |
|
PR is #472 |
When using S3 or GCS cache with bucket lifecycle rules to automatically delete old objects, imageproxy can get "poisoned" with empty cache entries. This happens because the cache returns empty data (
[]byte{}, true) instead of a cache miss (nil, false), causing httpcache to serve blank responses.This PR fixes the issue by treating zero-length objects as cache misses in both S3 and GCS cache implementations.
s3cache.Get()andgcscache.Get()s3iface.S3APIinterface for testabilityNewWithClient/NewWithBucketconstructors for dependency injectionFixes #248
/cc @Ladybiss @mdkent